using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Pavilion;

namespace Pavilion.Control
{
    public class DropDownMenu : Control
    {
        private Rectangle itemBounds;
        private Panel panel;

        public DropDownMenu() : base()
        {
            Initialize();
        }

        public DropDownMenu(DropDownItem[] dropDownItems) : base()
        {
            Initialize();
            AddRange(dropDownItems);
        }

        private void Initialize()
        {
            AreaBounds = new Rectangle(0, 0, 120, 0);
            itemBounds = new Rectangle(3, 0, AreaBounds.Width - 6, 20);
            panel = new Panel(AreaBounds);

            _Collection.Add(panel);

            this.Input.OuterClick += new Action<MouseCursor>(DropDownMenu_OuterClick);
            this.Resize += new EventHandler(DropDownMenu_Resize);
        }

        public override void Draw()
        {
            if (!Visible)
                return;

            //Draw shadow
            DrawManager.Instance.FillRectangleOnScreen(new Rectangle(ScreenBounds.X + 3, ScreenBounds.Y + 3, ScreenBounds.Width, ScreenBounds.Height), new Color(128, 128, 128, 128));
            //Draw Panel
            //spriteBatch.FillRectangle(ScreenBounds, BackgroundColor);
            base.Draw();

            //spriteBatch.DrawRectangle(ScreenBounds, OutlineColor);
        }

        /// <summary>
        /// Displays the drop down menu on top of the Root Control.
        /// </summary>
        public void Show()
        {
            Show(new Point((int)RootControl.Instance.MouseCursor.Position.X, (int)RootControl.Instance.MouseCursor.Position.Y));
        }

        /// <summary>
        /// Displays the drop down menu on top of the Root Control.
        /// </summary>
        /// <param name="position">The screen position of where the menu is to be displayed.</param>
        public void Show(Point position)
        {
            this.Visible = true;
            RootControl.Instance.Collection.Add(this);
            Position = position;
        }

        /// <summary>
        /// Adds a DropDownItem to this menu.
        /// </summary>
        public void AddItem(DropDownItem item)
        {
            panel.Collection.Add(item);
            ConfigureItem(ref item);
        }

        /// <summary>
        /// Inserts the item into the menu
        /// </summary>
        /// <param name="index">Where to insert the item</param>
        /// <param name="item">The item that is to be inserted.</param>
        public void Insert(int index, DropDownItem item)
        {
            panel.Collection.Insert(index, item);
            ConfigureItem(ref item);
        }

        /// <summary>
        /// Adda range of items to this menu.
        /// </summary>
        /// <param name="dropDownItems">The item that is to be removed.</param>
        public void AddRange(DropDownItem[] dropDownItems)
        {
            for (int i = 0; i < dropDownItems.Length; i++)
                AddItem(dropDownItems[i]);
        }

        /// <summary>
        /// Removes the list of items in this menu.
        /// </summary>
        public void Clear()
        {
            panel.Collection.Clear();
            Refresh();
        }

        /// <summary>
        /// Removes an item from the menu.
        /// </summary>
        /// <param name="item">The item that is to be removed.</param>
        public bool Remove(DropDownItem item)
        {
            if (panel.Collection.Remove(item))
            {
                Refresh();
                return true;
            }
            return false;
        }

        private void ConfigureItem(ref DropDownItem item)
        {
            item.AreaBounds = new Rectangle(itemBounds.X, (Count - 1) * itemBounds.Height, itemBounds.Width, itemBounds.Height);
            AreaBounds = new Rectangle(AreaBounds.X, AreaBounds.Y, AreaBounds.Width, Count * itemBounds.Height);
            item.Input.MouseRelease += new MouseObjectHandler(DropDownMenu_Hide);
        }

        private void Refresh()
        {
            for (int i = 0; i < Count; i++)
                this[i].AreaBounds = new Rectangle(itemBounds.X, i * itemBounds.Height, itemBounds.Width, itemBounds.Height);

            AreaBounds = new Rectangle(AreaBounds.X, AreaBounds.Y, AreaBounds.Width, Count * itemBounds.Height);
        }

        /// <summary>
        /// Gets the amount of items that are in this DropDownMenu.
        /// </summary>
        public int Count
        {
            get { return panel.Collection.Count; }
        }

        /// <summary>
        /// Gets or sets the width the DropDownMenu.
        /// </summary>
        public int Width
        {
            get { return AreaBounds.Width; }
            set
            {
                if (AreaBounds.Width == value)
                    return;

                AreaBounds = new Rectangle(AreaBounds.X, AreaBounds.Y, value, AreaBounds.Height);
                itemBounds = new Rectangle(itemBounds.X, itemBounds.Y, AreaBounds.Width - 6, itemBounds.Height);
                Refresh();
            }
        }

        /// <summary>
        /// Gets or sets the value at the given index.
        /// </summary>
        /// <param name="index">An index within this array list.</param>
        public DropDownItem this[int index]
        {
            get { return (DropDownItem)panel.Collection[index]; }
            set 
            {
                panel.Collection[index] = value;
                value.Input.MouseRelease += new MouseObjectHandler(DropDownMenu_Hide);
            }
        }

        private void DropDownMenu_Resize(object sender, EventArgs e)
        {
            panel.AreaBounds = new Rectangle(panel.AreaBounds.X, panel.AreaBounds.Y, AreaBounds.Width, AreaBounds.Height);
        }

        private void DropDownMenu_OuterClick(MouseCursor mouseCursor)
        {
            DropDownMenu_Hide(null, mouseCursor);
        }

        private void DropDownMenu_Hide(object sender, MouseCursor mouseCursor)
        {
            if (sender != null && ((DropDownItem)sender).Count > 0)
                return;

            this.Visible = false;
            DetachFromParent();
        }
    }
}
